﻿/* *****************************************************************************
 * @ Encoding: UTF-8
 * @ File Name: naughty_differential_node_log.cpp
 * @ Author: carl
 * @ Email: naughtygeng@qq.com
 * @ Created Time: 2022-7月-12(星期二) 19:20:49
 * @ All Rights Reserved
 * *****************************************************************************/

#include "naughty_differential_node_log.hpp"
#include "naughty_differential_node_div.hpp"
#include "naughty_differential_node_mul.hpp"
#include "naughty_differential_node_sub.hpp"
#include "naughty_differential_node_ln.hpp"
#include "naughty_differential_node_pow.hpp"
#include "naughty_differential_node_num.hpp"

namespace naughty_differential
{

node_log::node_log(std::shared_ptr<node_base> param01, std::shared_ptr<node_base> param02)
    :
        node_base({param01, param02})
{

}

node_log::node_log(std::vector<std::shared_ptr<node_base>> params)
    :
        node_base(params)
{

}

enum node_type node_log::get_node_type()
{
    return node_type_log;
}

std::shared_ptr<node_base> node_log::clone()
{
    return std::make_shared<node_log>(parameters_clone());
}

std::string node_log::to_string() const
{
    return std::string("log((") + get_parameters()[0]->to_string() + "), (" + get_parameters()[1]->to_string() + "))";
}

std::string node_log::serialize()
{
    return {};
}

std::shared_ptr<node_base> node_log::differential(std::string variable)
{
    return std::make_shared<node_div>(
        std::make_shared<node_sub>(
            std::make_shared<node_mul>(
                std::make_shared<node_div>(
                    get_parameters()[1]->differential(variable)
                    ,
                    get_parameters()[1]
                )
                ,
                std::make_shared<node_ln>(
                    get_parameters()[0]
                )
            )
            ,
            std::make_shared<node_mul>(
                std::make_shared<node_div>(
                    get_parameters()[0]->differential(variable)
                    ,
                    get_parameters()[0]
                )
                ,
                std::make_shared<node_ln>(
                    get_parameters()[1]
                )
            )
        )
        ,
        std::make_shared<node_pow>(
            std::make_shared<node_ln>(
                get_parameters()[0]
            )
            ,
            std::make_shared<node_num>(2)
        )
    );
}

double node_log::get_value(std::map<std::string, double> val_value_map)
{
    std::vector<double> params_value = get_params_value(val_value_map);

    return std::log2(params_value[1]) / std::log2(params_value[0]);
}

std::string node_log::identity_string() const
{
    return std::string("log((") + get_parameters()[0]->to_string() + "), (" + get_parameters()[1]->to_string() + "))";
}

}
